/************************************************************************
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 ************************************************************************/
package com.unis.common.util;

import org.apache.commons.lang.StringUtils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 时间格式转换工具类
 *
 * @author CSJ (email:raulcsj@163.com)
 * @since 2013-1-25
 */
public class TimeUtil {
    private static final String DEFAULT_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";

    private TimeUtil() {
    }

    /**
     * 根据指定格式转换Date为String
     *
     * @param date
     * @param fmt  如果为空，默认为：yyyy-MM-dd HH:mm:ss
     * @return
     */
    public static String fmtDate(Date date, String fmt) {
        if (date == null) {
            return "";
        }
        String str_date = "";
        if (fmt == null || "".equals(fmt.trim())) {
            fmt = DEFAULT_TIME_FORMAT;
        }
        SimpleDateFormat sdf = new SimpleDateFormat(fmt);
        str_date = sdf.format(date);
        return str_date;
    }

    /**
     * 把指定格式的String类型日期转换为Date
     *
     * @param str_date
     * @param fmt      如果为空，默认为：yyyy-MM-dd HH:mm:ss
     * @return
     * @throws ParseException
     */
    public static Date strToDate(String str_date, String fmt) throws ParseException {
        Date date = null;
        if (fmt == null || "".equals(fmt.trim())) {
            fmt = DEFAULT_TIME_FORMAT;
        }
        SimpleDateFormat sdf = new SimpleDateFormat(fmt);
        date = sdf.parse(str_date);
        return date;
    }

    /****************************************
     * 根据格式生成当前时间
     *
     * @param pattern
     * @return
     ****************************************/
    public static final String getNow(String pattern) {
        final SimpleDateFormat dateFormat = new SimpleDateFormat();
        if (StringUtils.isBlank(pattern)) {
            pattern = DEFAULT_TIME_FORMAT;
        }
        dateFormat.applyPattern(pattern);
        return dateFormat.format(new Date());
    }

    public static final String getNow() {
        return getNow(null);
    }

    /**
     * @author zxp yyyy-MM-dd HH:mm:ss
     **/
    public static final String getNow_(String pattern) {
        final SimpleDateFormat dateFormat = new SimpleDateFormat();
        if (StringUtils.isBlank(pattern)) {
            pattern = "yyyy-MM-dd HH:mm:ss";
        }
        dateFormat.applyPattern(pattern);
        return dateFormat.format(new Date());
    }

    /****************************************
     * 解析时间字符串
     *
     * @param data
     * @return
     ****************************************/
    public static final String parseDate(String data, String sourceFormat, String destFormat) {
        final SimpleDateFormat dateFormat = new SimpleDateFormat();
        if (StringUtils.isBlank(sourceFormat)) {
            sourceFormat = DEFAULT_TIME_FORMAT;
        }
        if (StringUtils.isBlank(destFormat)) {
            destFormat = DEFAULT_TIME_FORMAT;
        }
        dateFormat.applyPattern(sourceFormat);
        try {
            Date time = dateFormat.parse(data);
            dateFormat.applyPattern(destFormat);
            return dateFormat.format(time);
        } catch (ParseException e) {
            return e.getMessage();
        }
    }

    public static final String parseDate(String data, String sourceFormat) {
        return parseDate(data, sourceFormat, null);
    }

    public static final String parseDate(String data) {
        return parseDate(data, null, null);
    }

    /**
     * 格式化Date
     */
    public static final String formatDate(Date date, String format) {
        final SimpleDateFormat dateFormat = new SimpleDateFormat();
        if (StringUtils.isBlank(format)) {
            format = DEFAULT_TIME_FORMAT;
        }
        return dateFormat.format(date);
    }

    public static final String formatDate(Date date) {
        return formatDate(date, "");
    }

    // 日期转化为大小写
    public static String dataToUpper(String dateStr) {
        String res = "";
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        Date date = null;
        try {
            date = df.parse(dateStr);
        } catch (Exception e) {
            // 日期型字符串格式错误
            System.out.println("日期型字符串格式错误");
        }
        if (date != null) {
            Calendar ca = Calendar.getInstance();
            ca.setTime(date);
            int year = ca.get(Calendar.YEAR);
            int month = ca.get(Calendar.MONTH) + 1;
            int day = ca.get(Calendar.DAY_OF_MONTH);
            res = numToUpper(year) + "年" + monthToUppder(month) + "月" + dayToUppder(day) + "日";
        }
        return res;
    }

    // 将数字转化为大写
    public static String numToUpper(int num) {
        // String u[] = {"〇","壹","贰","叁","肆","伍","陆","柒","捌","玖"};
        String u[] = {"零", "一", "二", "三", "四", "五", "六", "七", "八", "九"};
        char[] str = String.valueOf(num).toCharArray();
        String rstr = "";
        for (int i = 0; i < str.length; i++) {
            rstr = rstr + u[Integer.parseInt(str[i] + "")];
        }
        return rstr;
    }

    // 月转化为大写
    public static String monthToUppder(int month) {
        if (month < 10) {
            return numToUpper(month);
        } else if (month == 10) {
            return "十";
        } else {
            return "十" + numToUpper(month - 10);
        }
    }

    // 日转化为大写
    public static String dayToUppder(int day) {
        if (day < 20) {
            return monthToUppder(day);
        } else {
            char[] str = String.valueOf(day).toCharArray();
            if (str[1] == '0') {
                return numToUpper(Integer.parseInt(str[0] + "")) + "十";
            } else {
                return numToUpper(Integer.parseInt(str[0] + "")) + "十" + numToUpper(Integer.parseInt(str[1] + ""));
            }
        }
    }

    /**
     * 获取年龄
     *
     * @param csrq
     * @return
     */
    public static String getNl(String csrq) throws Exception {
        if (StringUtils.isNotBlank(csrq)) {
            DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
            Date rq = df.parse(csrq);
            Calendar cal = Calendar.getInstance();
            int curYear = cal.get(Calendar.YEAR);
            cal.setTime(rq);
            int rqYear = cal.get(Calendar.YEAR);
            return String.valueOf(curYear - rqYear);
        } else {
            return "";
        }
    }

    /**
     * 日期转化为大小写 emp:2016年01月01日
     *
     * @param date
     * @return
     */
    public static String getDateValFromDate(String date, String dateFlag) throws Exception {
        String resDate = "";
        if (date == null) {
            return resDate;
        } else {
            if (StringUtils.isNotBlank(date)) {
                resDate = date.trim();
                if ("D".equals(dateFlag)) {// yyyy-MM-dd 格式
                    if (resDate.length() >= 10) {
                        resDate = resDate.substring(0, 10);
                        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
                        Date dateTmp = format.parse(resDate);
                        SimpleDateFormat formatRes = new SimpleDateFormat("yyyy年MM月dd日");
                        resDate = formatRes.format(dateTmp);
                    }
                }
                if ("H".equals(dateFlag)) {
                    if (resDate.length() >= 13) {
                        resDate = resDate.substring(0, 13);
                        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH");
                        Date dateTmp = format.parse(resDate);
                        SimpleDateFormat formatRes = new SimpleDateFormat("yyyy年MM月dd日HH时");
                        resDate = formatRes.format(dateTmp);
                    }
                }
            }
            return resDate;
        }
    }

    public static Date addDay(Date date, int n) {
        Calendar cd = Calendar.getInstance();
        cd.setTime(date);
        cd.add(Calendar.DATE, n);//增加天
        return cd.getTime();
    }

    public static Date addMonth(Date date, int n) {
        Calendar cd = Calendar.getInstance();
        cd.setTime(date);
        cd.add(Calendar.MONTH, n);//增加月
        return cd.getTime();
    }

    public static Date addHour(Date date, int n) {
        Calendar cd = Calendar.getInstance();
        cd.setTime(date);
        cd.add(Calendar.HOUR_OF_DAY, n);//增加时
        return cd.getTime();
    }

    /**
     * 此方法不抛出异常，若转换异常则返回null
     *
     * @Description: 任意时间字符串转换成时间，无需指定解析模板
     * @param: date 日期类型字符串
     * @return: Date
     * @Author: xuk
     */
    public static Date parseStringToDate(String date) {
        Date result;
        if (StringUtils.isNotBlank(date)) {
            String parse = date.replaceFirst("[0-9]{4}([^0-9]?)", "yyyy$1");
            parse = parse.replaceFirst("^[0-9]{2}([^0-9]?)", "yy$1");
            parse = parse.replaceFirst("([^0-9]?)[0-9]{1,2}([^0-9]?)", "$1MM$2");
            parse = parse.replaceFirst("([^0-9]?)[0-9]{1,2}( ?)", "$1dd$2");
            parse = parse.replaceFirst("( ?)[0-9]{1,2}([^0-9]?)", "$1HH$2");
            parse = parse.replaceFirst("([^0-9]?)[0-9]{1,2}([^0-9]?)", "$1mm$2");
            parse = parse.replaceFirst("([^0-9]?)[0-9]{1,2}([^0-9]?)", "$1ss$2");
            DateFormat format = new SimpleDateFormat(parse);
            try {
                result = format.parse(date);
            } catch (ParseException e) {
                e.printStackTrace();
                return null;
            }
        } else {
            return null;
        }
        return result;
    }

    /**
     * 根据一段时间区间，按月份拆分成多个时间段
     *
     * @param d1 开始日期
     * @param d2 结束日期
     * @return
     */
    @SuppressWarnings("deprecation")
    public static List<Map> getKeyValueForDate(Date d1, Date d2) {
        List<Map> list = null;
        try {
            list = new ArrayList<Map>();
            Date lastDay = null;

            Calendar dd = Calendar.getInstance();// 定义日期实例
            dd.setTime(d1);// 设置日期起始时间
            Calendar c = Calendar.getInstance();
            c.setTime(d2);
            //SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
            Map map = null;

            while (dd.getTime().before(d2)) {// 判断是否到结束日期
                map = new HashMap();
                //cale.setTime(dd.getTime());

                if (dd.getTime().equals(d1)) {
                    // cale.set(Calendar.DAY_OF_MONTH, dd.getActualMaximum(Calendar.DAY_OF_MONTH));
                    //lastDay = sdf.format(cale.getTime());
                    lastDay = TimeUtil.addDay(d1, 28);
                    map.put("kssj", d1);
                    map.put("jssj", lastDay);
                } else if (dd.get(Calendar.MONTH) == d2.getMonth() && dd.get(Calendar.YEAR) == c.get(Calendar.YEAR)) {
                    //cale.set(Calendar.DAY_OF_MONTH,1);//取第一天
                    //firstDay = sdf.format(cale.getTime());
                    map.put("kssj", lastDay);
                    lastDay = d2;
                    map.put("jssj", lastDay);
                    //System.out.println(d2.toString().length());
                    /*if(d2.toString().length()==28){
                        lastDay = d2;
                        map.put("jssj",TimeUtil.fmtDate(lastDay,"yyyyMMdd"));
                    }else{
                        lastDay = d2;
                        map.put("jssj",lastDay);
                    }*/

                } else {
                    map.put("kssj", lastDay);
                    lastDay = TimeUtil.addDay(lastDay, 28);
                    if (lastDay.before(d2)) {

                    } else {
                        lastDay = d2;
                    }
                    map.put("jssj", lastDay);
                }
                list.add(map);
                dd.setTime(lastDay);
            }
                /*if(endDay<startDay){
                    map = new HashMap();

                    cale.setTime(d2);
                    cale.set(Calendar.DAY_OF_MONTH,1);//取第一天
                    firstDay = sdf.format(cale.getTime());

                    map.put("kssj",firstDay);
                    map.put("jssj",sdf.format(d2));
                    list.add(map);
                }*/
        } catch (Exception e) {
            return null;
        }
        return list;
    }

    /**
     * 判断两个时间，间隔天数。
     *
     * @param d1
     * @param d2
     * @return
     * @throws ParseException
     */
    public static int getBetweenDays(Date d1, Date d2)
            throws ParseException {
        //SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
        int betweenDays = 0;
        //Date d1 = format.parse(t1);
        //Date d2 = format.parse(t2);
        Calendar c1 = Calendar.getInstance();
        Calendar c2 = Calendar.getInstance();
        c1.setTime(d1);
        c2.setTime(d2);
        // 保证第二个时间一定大于第一个时间
        if (c1.after(c2)) {
            c1 = c2;
            c2.setTime(d1);
        }
        int betweenYears = c2.get(Calendar.YEAR) - c1.get(Calendar.YEAR);
        betweenDays = c2.get(Calendar.DAY_OF_YEAR)
                - c1.get(Calendar.DAY_OF_YEAR);
        for (int i = 0; i < betweenYears; i++) {
            c1.set(Calendar.YEAR, (c1.get(Calendar.YEAR) + 1));
            betweenDays += c1.getMaximum(Calendar.DAY_OF_YEAR);
        }
        return betweenDays;
    }

    public static void main(String[] args) {
        List<Map> list = null;
        try {
            //System.out.println(TimeUtil.fmtDate(TimeUtil.parseStringToDate("2019-04-12"),"yyyyMMdd"));
            //System.out.println(TimeUtil.getBetweenDays("20190201","20190321"));
            list = TimeUtil.getKeyValueForDate(TimeUtil.parseStringToDate("20190715"), TimeUtil.parseStringToDate("20190813"));
            System.out.println(TimeUtil.getBetweenDays(TimeUtil.parseStringToDate("20190715"), TimeUtil.parseStringToDate("20190812")) > 27);
            if (TimeUtil.getBetweenDays(TimeUtil.parseStringToDate("20190715"), TimeUtil.parseStringToDate("20190813")) > 28) {
                for (int i = 0; i < list.size(); i++) {
                    System.out.println("@@" + TimeUtil.fmtDate((Date) list.get(i).get("kssj"), null) + "~~~" + TimeUtil.fmtDate((Date) list.get(i).get("jssj"), null));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
